﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
using System;
using System.IO;
using System.Text;


namespace KFGame
{
    /**
    ** 实现接口
    **  @creator   wind
    **   huangchonggao@21cn.com
    ** 在最初的启动时进行实例化， 在进行有游戏中只能实例化一次
    **/
    public class KF : KFGameFramework
    {
        private static KF _kf;
        public static KF kf
        {
            get
            {
                return KF.Instantiation();
            }
        }
        public static KF Instantiation()
        {
            if (enter)
                if (_kf == null)
                {
                    GameObject tkf = new GameObject("KF");
                    DontDestroyOnLoad(tkf);
                    _kf = tkf.AddComponent<KF>();
                    return _kf;
                }
            return _kf;
        }

#if UNITY_EDITOR
        /// <summary>
        /// 工程被加载后初始化
        /// </summary>
        [UnityEditor.InitializeOnLoadMethod]
        static void Init()
        {

            ///检测配置是并初始化文件 
            KFFile.InitFile("KFConfig/kfconfig");

            //键盘模拟配置
            KFFile.InitFile("KFConfig/kfkeyslisent");

            //IO com接项配置
            KFFile.InitFile("KFConfig/kfseralportconfig");
            KFFile.InitFile("KFConfig/kfseralportevents");
            KFFile.InitFile("KFConfig/kfseralporteventstofkevent");
           

            //后台设置项配置
            KFFile.InitFile("KFConfig/kfsetting");
            //后台统计项配置
            KFFile.InitFile("KFConfig/statistics");
        }
#endif

    }

    //
    //KFGame 游戏管理框架，
    // @creator   wind
    // huangchonggao@21cn.com
    // 管理流程和外部对接加载Scene
    //
    [DisallowMultipleComponent]
    public class KFGameFramework : MonoBehaviour
    {
        public static bool enter = true;
        //框架版本
        public const string vesion = "1.0.0";
        //FK Scene Name
        public const string KFGameFrameworkScene = "KF_Main_Scene";
        //框架名称
        public const string frameworkName = "KF_Game_Framework";
        /// <summary>
        /// 开发调式模式,开发时设为true 
        /// 发布时设为false， 
        /// </summary> 
        public static bool isDebug = true;

        /// <summary>
        /// 授权模式
        /// 发布需要授权时设为true
        /// </summary>
        public static bool authentication = false;

        /// <summary>
        /// 场景管理
        /// </summary>
        [HideInInspector]
        public KFSceneManager sceneManager;


        //启动加载的场景 
        //"启动框架时，第一次加载的场景，需要在buidSetting中设置"
        [HideInInspector]
        public string FirstScene = "KFStartScene";
        //是否启动时加载 StartScene
        [HideInInspector]
        public bool runFirstScene = false;
        //主要的游戏场景的Scene 
        [HideInInspector]
        public string MainScene;

        // 安全管理组件 启动游戏时验证启动指纹
        [HideInInspector]
        public bool isStartSession = true;





        //侦率设定，需要设定限侦才起作用 limit_FPS
        [HideInInspector]
        public int FPS = 30;
        //"需要在 project settings 中 V sync count 设为 Don't Sync"
        [HideInInspector]
        public bool limit_FPS = true;
        [HideInInspector]
        public bool show_FPS = true;

        //使用鍵盘侦听器
        [HideInInspector]
        public bool isKeyboardLisent = true;


        /// <summary>
        ///  邮件系统
        /// </summary>
        private KFSendEmail _email;
        public KFSendEmail Email
        {
            get
            {
                if (_email == null)
                    _email = KFSendEmail.instantiation();
                return _email;
            }
        }


        /// <summary>
        /// 配置记录 
        /// 游戏配置初始化
        /// </summary>
        private GameConfigData _gameconfig;
        public GameConfigData config
        {
            get
            {
                if (_gameconfig == null)
                    _gameconfig = GameConfigData.instantiation();
                return _gameconfig;
            }
        }

        /// <summary>
        /// 设置系统
        /// </summary>
        private static KFSetting _setting;
        public static KFSetting setting
        {
            get
            {
                if (_setting == null)
                    _setting = KFSetting.instantiation();
                return _setting;
            }
        }


        /// <summary>
        /// 框架的应用系统
        /// </summary>
        private KFApplication _app;
        public KFApplication app
        {
            get
            {
                if (_app == null)
                    _app = gameObject.AddComponent<KFApplication>();
                return _app;
            }
        }

        /// <summary>
        /// 键盘处理
        /// </summary>
        private KeyboardSimulation _keyboard;
        public KeyboardSimulation keyboard
        {
            get
            {
                if (_keyboard == null)
                    _keyboard = gameObject.AddComponent<KeyboardSimulation>();
                return _keyboard;
            }
        }

        /// <summary>
        /// 事件管理器
        /// </summary>
        /// <value></value>
        private KFEventManager _kfevents;
        public KFEventManager kfevents
        {
            get
            {
                if (_kfevents == null)
                    _kfevents = gameObject.AddComponent<KFEventManager>();
                return _kfevents;
            }
        }

        /// <summary>
        /// 网络管理器
        /// </summary>
        private KFNetWork _kfnetwork;
        public KFNetWork netWorkManager
        {
            get
            {
                if (_kfnetwork == null)
                    _kfnetwork = gameObject.AddComponent<KFNetWork>();
                return _kfnetwork;
            }
        }

        /// <summary>
        /// 任务管理器 
        /// </summary>
        private KFServerTask _tasks;
        public KFServerTask taskManager
        {
            get
            {
                if (_tasks == null)
                    _tasks = gameObject.AddComponent<KFServerTask>();
                return _tasks;
            }
        }



        /// <summary>
        /// 调试日志记录
        /// </summary>
        /// <param name="str"></param>
        public static void Log(string str)
        {
            //if (isDebug)
            //    Debug.LogFormat("{0} DEBUG MODE -> {1}", frameworkName, str);
            KFLog.Log(str);
        }



        /// <summary>
        /// 读写 安装锁
        /// </summary>
        void lockInstall()
        {
            string fname = "KFGAME.install";
            string path = Application.streamingAssetsPath + "/KFConfig/" + fname;
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);

            StreamReader sr = new StreamReader(fs, Encoding.UTF8);

            string n = sr.ReadToEnd().Trim();
            sr.Close();
            fs.Close();


            if (Application.productName != n)
            {
                fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
                StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);/*创建读写器*/

                sw.Write(Application.productName);/*读写*/

                sw.Close();/*关闭读写器*/
                fs.Close();/*关闭文件流*/
            }




        }
        /// <summary>
        /// 启动初始化
        /// </summary>
        void Awake()
        {
            Log("KF Game Framework running");

            //配置
            initConfig();
            //安装器
            lockInstall();


            //场景管理
            sceneManager = gameObject.AddComponent<KFSceneManager>();

            if (limit_FPS)
                Application.targetFrameRate = FPS;

            //串口接口连接 管理初始化
            KFSeralPort.isDebug = isDebug;
            KFSeralPort.init();
            KFSeralPort.OpenAll();

            InitCurrentScene();

        }



        /// <summary>
        /// 初始化 读取配置
        /// </summary>
        void initConfig()
        {
            INIParser par = KFConfig.open();

            FirstScene = par.ReadValue(KFConfig.group, "FirstScene", "KFStartScene");
            MainScene = par.ReadValue(KFConfig.group, "Scene", "KFGameScene");
            runFirstScene = par.ReadValue(KFConfig.group, "runFirstScene", false);

            isDebug = par.ReadValue(KFConfig.group, "debug", false);

            FPS = par.ReadValue(KFConfig.group, "FPS", 30);
            limit_FPS = par.ReadValue(KFConfig.group, "FPS_limit", false);
            show_FPS = par.ReadValue(KFConfig.group, "FPS_show", false);

            isKeyboardLisent = par.ReadValue(KFConfig.group, "KeyboardLisent", false);

            par.Close();

            Log(" loaded configs ");
        }

        /// <summary>
        /// 启动指纹验证
        /// </summary>
        void startSession()
        {
            string[] args = Environment.GetCommandLineArgs();


            if (!authentication)
            {
                Log("applaction loading  session :" + config.session + " is not " + args.ToString());
                return;
            }

            if (Application.isEditor)
                return;


            int ktag = -1;
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "KF-APP")
                {
                    ktag = i;
                    break;
                }
            }

            if (-1 == ktag)
            {
                Log("dont run game error : no find tag ");
                Application.Quit();
                return;
            }

            string t = args[ktag + 1];
            string mark = args[ktag + 2];
            DateTime dt = Convert.ToDateTime(t);
            DateTime nt = DateTime.Now;
            long md = nt.ToFileTimeUtc() - dt.ToFileTimeUtc();
            TimeSpan secondSpan = new TimeSpan(nt.Ticks - dt.Ticks);
            if (secondSpan.TotalSeconds > 120)
            {
                Log("run game time out");
                Application.Quit();
                return;
            }


            string ndis = "KFGameApp";
            string md32 = AuSecurity.Get_md_32(ndis + t);
            if (md32 != mark)
            {
                Log("run game   session error: new->" + md32 + " : source-> " + mark);
                Application.Quit();
                return;
            }

            return;
        }

        /// <summary>
        /// 初始化完成后运行
        /// </summary>
        void Start()
        {

            //验证指纹
            if (isStartSession)
                startSession();


            //键盘侦听
            if (isKeyboardLisent)
            {
                keyboard.loadKFKey();
                keyboard.load();
            }


            //应用实例
            _app = gameObject.AddComponent<KFApplication>();

            //启动第一界面
            if (runFirstScene)
                sceneManager.LoadScene(FirstScene);

            //邮件服务务 
            Email.inits();
        }


        /// <summary>
        /// 初始化场景
        /// </summary>
        public void InitCurrentScene()
        {
            Scene scene = SceneManager.GetActiveScene();
            sceneManager.addSceneName(scene.name);
        }

        /// <summary>
        /// 只添加一次的组件 不会重复添加
        /// </summary>
        /// <param name="name"> 组件名称</param>
        /// <returns>组件对象</returns>
        public Component AddOnceComponent(string name)
        {
            var c = getComponet(name);
            return (c != null) ? c : AddComponent(name);
        }

        /// <summary>
        /// 添加组件到框加上
        /// </summary>
        /// <param name="name"> 组件名称</param>
        /// <returns>组件对象</returns>
        public Component AddComponent(string name)
        {
            return gameObject.AddComponent(System.Type.GetType(name));
        }

        /// <summary>
        /// 移除组件
        /// </summary>
        /// <param name="name">组件名称</param>
        /// <returns> true 时组件存在并成功消毁</returns>
        public bool RemoveComponent(string name)
        {
            var c = getComponet(name);
            if (c != null)
            {
                Destroy(c);
                return true;
            }
            return false;
        }


        /// <summary>
        /// 取得组件对象
        /// </summary>
        /// <param name="name">组件名称</param>
        /// <returns></returns>
        public Component getComponet(string name)
        {
            return GetComponent(System.Type.GetType(name));
        }




        /// <summary>
        /// 框加被消毁时系统自动调用，一般情况只有程序结束时
        /// 在结束前做一些处理
        /// </summary>
        public void OnDestroy()
        {

            enter = false;
            Log(" framework  on Destroy");
            // config.save();
            KFSeralPort.CloseALL();
        }

        /// <summary>
        /// 应用程序结束时系统自动调用，在结束前做一些处理
        /// </summary>
        private void OnApplicationQuit()
        {
            Log(" Application Quit ");
        }
    }

}